/**
 * 
 */
package com.jy.modules.cims.transexception.service;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.jy.modules.cims.common.CimsConstant;
import com.jy.modules.cims.common.exception.CimsExceptionConstant;
import com.jy.modules.cims.common.sysUtils.SpringContextUtils;
import com.jy.modules.cims.component.common.service.TCMmTransConfigService;
import com.jy.modules.cims.data.common.dto.TCMmCooperorgDealDTO;
import com.jy.modules.cims.data.common.dto.TCMmTransConfigDTO;
import com.jy.modules.cims.data.dto.credit.RedeemResultDto;
import com.jy.modules.cims.interact.IInteractAssist;

/**
 * @author jieyue
 *
 */
@Service("com.jy.modules.cims.transexception.service.CommonTransExceptionService")
public class CommonTransExceptionService {
	
	private static final Logger logger = LoggerFactory.getLogger(CommonTransExceptionService.class);
	
	@Autowired
	@Qualifier("com.jy.modules.cims.interact.CInteractAssist")
	public IInteractAssist iInteractAssist;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmTransConfigService")
    private TCMmTransConfigService transConfigService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.transexception.service.TransExceptionService")
    private TransExceptionService transExceptionService;
	
	@Autowired
    public SpringContextUtils springContextUtil;

	/**
	 * 反射机制调用
	 * 调用XX对象的XX方法
     * @Title doReflectInvokeMethodName
     * @Description TODO
     * @return 
     * @author yanjingying
     * @date 2015-1-08-下午11:47:00
     * @update
	 * @throws Exception 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 * @throws ClassNotFoundException 
	 * */
	public Map<String, Object> doReflectInvokeMethodName(Object obj, String methodName, Object[] args) throws 
						ClassNotFoundException, NoSuchMethodException, 
						SecurityException, IllegalAccessException, 
						IllegalArgumentException, InvocationTargetException{
		Object bean = null;
		Class<?> myClass = null;
		Class[] argsClass = new Class[args.length];   
		Map<String, Object> hashMap = new HashMap<String, Object>();
		for (int i = 0, j = args.length; i < j; i++) {   
		argsClass[i] = args[i].getClass();   
		}   
		if (obj instanceof String) {
		bean = springContextUtil.getBean((String)obj);
		myClass = Class.forName((String) obj);
		} else {
		bean = springContextUtil.getBean((Class)obj);
		myClass = obj.getClass();   //获取这个对象的Class
		}
		
		Method method = myClass.getMethod(methodName, argsClass); 
		hashMap = (Map<String, Object>) method.invoke(bean, args);
		return hashMap; 
	}
/*	public Map<String, Object> doReflectInvokeMethodName(Object obj, String methodName, Object[] args) throws Exception{
		Object bean = null;
		Class<?> myClass = null;
	    Class[] argsClass = new Class[args.length];   
	    Map<String, Object> hashMap = new HashMap<String, Object>();
	    try{
	    	for (int i = 0, j = args.length; i < j; i++) {   
		    	argsClass[i] = args[i].getClass();   
		    }   
		    if (obj instanceof String) {
				bean = springContextUtil.getBean((String)obj);
				myClass = Class.forName((String) obj);
			} else {
				bean = springContextUtil.getBean((Class)obj);
				myClass = obj.getClass();   //获取这个对象的Class
			}
			logger.info(DateUtil.getCurrentTime()+">>>>>>>>>>>>>>"+bean.toString()+">>>>>>>>>>>>>>");
			
		    Method method = myClass.getMethod(methodName, argsClass); 
		    try {
				hashMap = (Map<String, Object>) method.invoke(bean, args);
			} catch (IllegalAccessException e) {
				throw new Exception("执行doReflectInvokeMethodName异常：" +e.getMessage());
			}
	    }catch(IllegalArgumentException e){
	    	throw new Exception("执行doReflectInvokeMethodName异常：" +e.getMessage());
	    }catch(InvocationTargetException e){
	    	Throwable t = ((InvocationTargetException) e).getTargetException();
	    	throw new Exception("执行doReflectInvokeMethodName异常：" + t.getMessage());
	    }catch(NoSuchMethodException e){
	    	throw new Exception("执行doReflectInvokeMethodName异常：" + e.getMessage());
	    }catch(SecurityException e){
	    	throw new Exception("执行doReflectInvokeMethodName异常：" + e.getMessage());
	    }catch(ClassNotFoundException e){
	    	throw new Exception("执行doReflectInvokeMethodName异常：" + e.getMessage());
	    }
	    return hashMap; 
	}*/
	
	/**
	 * 通用事务调用方法
	 * @Title doInvokeCommonTrans
     * @Description TODO
     * @return 
     * @author yanjingying
     * @date 2015-1-08-下午11:47:00
     * @update
	 * @throws Exception 
	 * */
	public Map<String, String> doInvokeCommonTrans(String transEnName, String TransNo, Object obj, String methodName, 
			String dealCode, String frontTransNo) throws Exception{
		if(frontTransNo == null || "".equals(frontTransNo)){
			frontTransNo = iInteractAssist.getInteractNo();   //获取前置接口交易流水号
    	}
		
		RedeemResultDto redeemResultDto = new RedeemResultDto();
		String retCode = ""; //返回码
		String retMsg = "";//返回message
		Map<String, String> resultMap = new HashMap<String, String>();
		TCMmTransConfigDTO transConfigDTO = new TCMmTransConfigDTO();
		Map<String, Object> searchParams = new HashMap<String, Object>();
		transConfigDTO.setTransEnName(transEnName);  //贷款回购交易发送核心整体事务
		transConfigDTO.setTransNo(TransNo);
		searchParams.put("dto", transConfigDTO);
		List<TCMmTransConfigDTO>  tCMmTransConfigDTOList = transConfigService.searchTCMmTransConfig(searchParams);
		if(tCMmTransConfigDTOList != null && tCMmTransConfigDTOList.size() > 0){
			//得到事务配置信息
			TCMmTransConfigDTO dto = tCMmTransConfigDTOList.get(0);
			try {
				TCMmCooperorgDealDTO cooperorgDealDTO = new TCMmCooperorgDealDTO();
				cooperorgDealDTO.setDealCode(dealCode);
				Object[] args = new Object[]{cooperorgDealDTO, frontTransNo};
				Map<String, Object> rsMap = (Map<String, Object>) this.doReflectInvokeMethodName(obj, methodName, args);
				redeemResultDto = (RedeemResultDto) rsMap.get("dto");
				retCode = redeemResultDto.getRetCode();
				if (CimsConstant.RET_CODE_SUC.equals(redeemResultDto.getRetCode())) {
					retMsg = dto.getTransDesc()+"调用成功!";
					redeemResultDto.setRetMsg(retMsg);
				}
				redeemResultDto.setFrontTransNo(frontTransNo);
				transExceptionService.saveTransException(dto, redeemResultDto, retCode, dealCode);
			} catch (Exception e) {
				String message = "";
				if(e instanceof InvocationTargetException){
					Throwable t = ((InvocationTargetException) e).getTargetException();
					message = t.getMessage();
					if (message.indexOf(CimsExceptionConstant.INTERACT_NETWORK_ERROR) > -1) {
						retCode = CimsConstant.RET_CODE_TIMEOUT;  //超时
					} else {
						retCode = CimsConstant.RET_CODE_FAIL;
					}
					retMsg =  dto.getTransDesc() + "调用失败："+ message +"!";
					retMsg = retMsg.length() > 100 ? retMsg.substring(0, 100) : retMsg;
					redeemResultDto.setRetCode(retCode);
					redeemResultDto.setRetMsg(retMsg);
					redeemResultDto.setFrontTransNo(frontTransNo);
					transExceptionService.saveTransException(dto, redeemResultDto, retCode, dealCode);
				}else if(e instanceof NoSuchMethodException){
					message = "没有找到方法异常!" + e.getMessage();
				}else if(e instanceof IllegalArgumentException){
					message = "不合法参数异常!" + e.getMessage();
				}else if(e instanceof ClassNotFoundException){
					message = "类未找到异常!" + e.getMessage();
				}else if(e instanceof SecurityException){
					message = "权限不够异常!" + e.getMessage();
				}else if(e instanceof IllegalAccessException){
					message = "安全权限异常!" + e.getMessage();
				}else{
					message = e.getMessage();
				}
				logger.error( dto.getTransDesc()+"接口异常，异常信息如下："+ message);
				throw e;
			} 
		}else{
			retMsg = transEnName + "事务" + TransNo + "配置缺失!";
			retCode = CimsConstant.RET_CODE_FAIL;
		}
		resultMap.put("resultCode", retCode);
		resultMap.put("resultMsg", retMsg);
	
		return resultMap;
	}

}
